﻿using TianShu.SysParameterSetting.DAL.Abstracts;
using TianShu.SysParameterSetting.DAL.Abstracts.SystemParameterSetting;
using TianShu.SysParameterSetting.DAL.Abstracts.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TianShu;
using Volo.Abp.Caching;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.SqlSugarCore.Services;

namespace TianShu.SysParameterSetting.DAL.SystemParameterSettingManager
{
    public class SystemParameterSettingDalImpl : DalService, ISystemParameterSettingDal
    {
        protected IDistributedCache<SystemParamterSettingCacheDto> Cache { get; }
        protected IRepository<TianShu.SysParameterSetting.DAL.Abstracts.Entities.SystemParameterSetting, Guid> SystemParamterSettingRepository { get; }

        public SystemParameterSettingDalImpl(IDistributedCache<SystemParamterSettingCacheDto> cache
                                               , IRepository<TianShu.SysParameterSetting.DAL.Abstracts.Entities.SystemParameterSetting, Guid> systemParamterSettingRepository)
        {
            Cache = cache;
            SystemParamterSettingRepository = systemParamterSettingRepository;
        }
        public async Task<bool> AddOrUpdateSettingToCacheAsync(SystemParamterSettingCacheDto dto)
        {
            await SetCacheDataAsync(dto);
            return true;
        }
        public async Task<T> GetValue<T>(string code)
        {
            var dto = await GetCacheDataAsync(code);
            if (dto == null)
            {
                return default;
            }
            if (dto.Value.IsNullOrEmpty())
            {
                dto.Value = dto.DefaultValue;
            }
            try
            {
                var result = (T)Convert.ChangeType(dto.Value, typeof(T));
                return result;
            }
            catch (FormatException ex)
            {
                return default(T);
            }
        }

        public async Task SetDefaultValue(string code, string defaultValue)
        {
            await SetCacheDataAsync(new SystemParamterSettingCacheDto() { Code = code, DefaultValue = defaultValue });
        }

        public async Task<SystemParamterSettingCacheDto> GetSettingAsync(string code)
        {
            return await GetCacheDataAsync(code);
        }

        private async Task<SystemParamterSettingCacheDto> GetCacheDataAsync(string code)
        {
            var key = CacleCacheKey(code);
            var dto = await Cache.GetAsync(key);
            if (dto == null)
            {
                var entity = await SystemParamterSettingRepository.FindAsync(e => e.Code == code);
                if (entity == null)
                {
                    return new SystemParamterSettingCacheDto()
                    {
                        DefaultValue = ""
                    };
                }
                dto = EntityToDto(entity);
            }
            return dto;
        }

        private async Task<SystemParamterSettingCacheDto> SetCacheDataAsync(SystemParamterSettingCacheDto dto)
        {
            var key = CacleCacheKey(dto.Code);
            var cacheDto = await Cache.GetAsync(key);
            if (cacheDto == null)
            {
                cacheDto = new SystemParamterSettingCacheDto();
            }
            cacheDto.Name = dto.Name;
            cacheDto.Remark = dto.Remark;
            cacheDto.Value = dto.Value;
            await Cache.SetAsync(key, cacheDto);
            return dto;
        }


        public SystemParamterSettingCacheDto EntityToDto(TianShu.SysParameterSetting.DAL.Abstracts.Entities.SystemParameterSetting dto)
        {
            return new SystemParamterSettingCacheDto
            {
                Code = dto.Code,
                Name = dto.Name,
                Remark = dto.Remark,
                TenantId = dto.TenantId,
                Value = dto.Value,
                DefaultValue = default
            };
        }

        public string CacleCacheKey(string key)
        {
            return $"{CurrentTenant.Id}_{key}";
        }

    }
}
